package org.auto;

import org.apache.commons.math3.ml.clustering.Cluster;
import org.apache.commons.math3.ml.clustering.DBSCANClusterer;
import org.apache.commons.math3.ml.clustering.DoublePoint;
import org.apache.commons.math3.ml.distance.DistanceMeasure;
import org.apache.commons.math3.ml.distance.EuclideanDistance;
import org.opencv.core.Core;
import org.test.GPSPoint;
import org.test.GPSUtils;
import org.test.TraceBoundaryProcessor;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

public class Test2 {

    public static void main(String[] args) throws Exception {

        // 加载 opencv_javaXX.dll
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        List<DoublePoint> pointList = new ArrayList<>();
        Map<String, Object[]> dataMap = new LinkedHashMap<>();

        InputStream is = Test2.class.getResourceAsStream("/data2.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        br.readLine(); //跳过标题行
        Integer idx = 0;
        while ((line = br.readLine()) != null) {
            // 进行抽稀
            if (idx++ % 6 == 0) {
                String[] arr = line.split("\\s+");
                GPSPoint rawPoint = new GPSPoint(Double.parseDouble(arr[0]), Double.parseDouble(arr[1]));

                GPSPoint xyPoint = GPSUtils.gps2xy(rawPoint);
                pointList.add(new DoublePoint(new double[]{xyPoint.lng, xyPoint.lat}));
                dataMap.put(xyPoint.lng + "_" + xyPoint.lat, new Object[]{idx, rawPoint});
            }
        }

        // 抽稀后，进行密度聚类。聚类后恢复点 //

        // 创建距离度量
        DistanceMeasure measure = new EuclideanDistance();
        // 创建并配置DBSCAN聚类器
        DBSCANClusterer<DoublePoint> clusterer = new DBSCANClusterer<>(100, 30, measure);
        // 执行聚类
        List<Cluster<DoublePoint>> clusterList = clusterer.cluster(pointList);
        System.out.println(clusterList.size());

        boolean debug = true;

        for (Cluster cl : clusterList) {
            System.out.println(cl.getPoints());

            if (debug) {
                // 根据点找到原始点，纬度有偏差
                List<DoublePoint> points = cl.getPoints();
                Map<Integer, GPSPoint> treeMap = new TreeMap<>();
                for (DoublePoint dp : points) {
                    double[] pt = dp.getPoint();
                    Object[] vals = dataMap.get(pt[0] + "_" + pt[1]);
                    treeMap.put((Integer) vals[0], (GPSPoint) vals[1]);
                }

                Collection<GPSPoint> traces = treeMap.values();
                Map<String, Object> map = TraceBoundaryProcessor.getTracesBoundaries(traces, 1, 1, 1, 4000, true, true);
                System.out.println(map);
            }
        }

    }
}
